import { lazy, Suspense, useEffect, useRef, useState, useImperativeHandle } from 'react'
/* -------------------------------------------------------- Declare -- */
const { $lazy, $, $fn } = window 
/* -------------------------------------------------------- Async Component -- */
const Button = lazy(()=>import('@antd/button'))
const Table = $lazy.hook(()=>import('@antd/table'))
const Input = lazy(()=>import('@antd/form/input'))
const Select = lazy(()=>import('@antd/form/select'))
const Date = lazy(()=>import('@antd/form/date-picker'))
const Switch = lazy(()=>import('@antd/form/switch'))
/* -------------------------------------------------------- 回到顶部 -- */
const Index = (props, ref)=> {// eslint-disable-line
	let { 
		name, 							/** @param {String}				# name */
		label,							/** @param {String}				# 标签名 */
		cols=[],						/** @param {Array}				# 标签名 */
		init=0,							/** @param {Boolan}				# 初始化是否有 */
		height='auto',					/** @param {Number/String}		# 表高 */
		summary,						/** @param {Component}			# summary */
		status=0,						/** @param {Boolan}				# 是否可以查看 0: 编辑全部; 1 仅查看; 2 动态编辑, 3 仅可输入，不可编辑 */
		//
		value,							/** @param {Number}				# 值 */
		disabled,						/** @param {Boolan}				# 禁用 */
		readOnly,						/** @param {Boolan}				# 禁用 */
		onChange,						/** @param {Event}				# 有 Form 时值改变时执行 */
		onChanged,						/** @param {Event}				# 值改变时执行 */
	} = props
	const tableRef = useRef()
	const dataRef = useRef([])
	const onceRef = useRef()
	const resetRef = useRef()
	const [ col, setCol ] = useState([])
	const [ keys, setKeys ] = useState([])
	const [ edit, setEdit ] = useState()
	const [ gray, setGray ] = useState()
	if( readOnly ) status = 1
	
	useEffect(() =>{ 
		if( status === 2 ){
			setEdit( false )
		}
	}, [status])
	
	const _change = (value, dataIndex,  row) => {
		onceRef.current = 1
		row[dataIndex] = value
		const ref = $.ref(tableRef)
		if(ref){
			ref.update()
			_onChange( ref.data() )
		}
	}
	
	useEffect(()=>{
		let c = []
		let v = { }
		cols.forEach( v => {
			const { title, dataIndex, width, align, type, mode, format, data, group, render, money, p} = v
			let disabled_ = $fn.isEmpty(v.disabled) ? disabled : v.disabled
			let readOnly_ = $fn.isEmpty(v.readOnly) ? readOnly : v.readOnly
			
			c.push({ 
				title, 
				dataIndex, 
				width, 
				align,
				render: render ? render : (text, row) => {
					if( status === 1 || readOnly_ || ( status === 2 && !edit ) ) {
						if(type === 'select'){
							return $fn.getState(data, text)
						}else{
							if( text ){
								return money ? text.toFixed(2) :text
							}else{
								return $fn.isEmpty(text) ? '--' : text
							}
						}
					}
					if( type === 'select' ){
						return <Select
							value		= { text }
							data 		= { data }
							group 		= { group }
							disabled 	= { disabled_ }
							p 			= { p ? p : (props.p ? '' : '选择') + title }
							onChange	= { v => _change(v, dataIndex, row)}
						/>
					}else if( type === 'date' ){
						return <Date
							value		= { text }
							format 		= { format }
							disabled 	= { disabled_ }
							p 			= { p ? p : (props.p ? '' : '选择') + title }
							onChange	= { v => _change(v, dataIndex, row)}
						/>
					}else if( type === 'switch' ){
						return <Switch
							value		= { text }
							disabled 	= { disabled_ }
							onChange	= { v => _change(v, dataIndex, row)}
						/>
					}else if( type === 'text'){
						return text
					}else{
						return <Input
							value		= {text}
							type 		= { mode }
							p 			= { p ? p : (props.p ? '' : '输入') + title }
							disabled 	= { disabled_ }
							onChange	= { v => _change(v, dataIndex, row)}
						/>
					}
				}
			})
			v[dataIndex] = ''
		})
		dataRef.current = [ v ]
		
		setCol([...c])
		setTimeout(() => $.ref(tableRef)?.data?.( init ? dataRef.current :[] ), 100)
	},[edit, disabled, readOnly]) // eslint-disable-line
	
	useEffect(()=> {
		if( !onceRef.current ){
			setTimeout(() => $.ref(tableRef)?.data?.( value  ), 100)
		}
	}, [ value, edit ]) // eslint-disable-line
	
	useEffect(()=> {
		if( !onceRef.current ){
			if( $fn.hasArray(value) ){
				resetRef.current = value
			}
		}
	}, [ value ]) // eslint-disable-line
	
	const table = {
		cols:col,
		isIndex: 1,
		height,
		row: (status === 0 || (edit && status === 2)) && !disabled ? {
			change: ({ keys }) => setKeys(keys)
		} : null,
		summary,
		controls : (status === 0 || (edit && status === 2)) ? {
			width: 100,
			data: v => [
				{ mode:'del', disabled:$fn.isEmpty(v.disabled) ? disabled : v.disabled,  click:({ index })=> {
					const ref = $.ref(tableRef)
					let d = ref.data()
					d.splice(index, 1)
					ref.data(d)
					_onChange( d )
				} }
			]
		} : null
	}
	
	const getData = data => {
		const arr = window.$fn.deepCopy(data)
		if( window.$fn.hasArray(arr)  ){
			return arr.filter( v => {
				let stack = []
				for(let k in v){
					if(k === 'i') delete v[k]
					if( v[k] === '' || v[k] === undefined || v[k] === null ){
						v[k] = null
						stack.push(k)
					}
				}
				return stack.length !== Object.keys(v).length
			})
		}else {
			return null
		}
	}
	
	const _onChange = value => {
		let result = name ? { model: {[name]: value} } : null
		let nodata = $fn.isArray(value) && value.length === 0
		if( nodata ) value = null
		setGray( nodata )
		value = getData(value)
		onChange?.( value )
		onChanged?.({ value, label, ...result  })
	}
	
	const onClear = () => {
		onceRef.current = 1
		const ref = $.ref(tableRef)
		ref.data([])
		ref.keys([])
		_onChange?.([])
	}
	
	const onDel = () => {
		onceRef.current = 1
		const ref = $.ref(tableRef)
		let _data = ref.data()
		let _keys = ref.keys()
		_data.forEach( (v,i) => {
			_keys.forEach( k =>{
				if( v.i === k )_data[i] = null
			} )
		} )
		
		ref.keys([])
		
		let d = _data.filter( v => v)
		
		ref.data(d)
		
		_onChange?.(d)
	}
	
	const onAdd = () => {
		onceRef.current = 1
		const ref = $.ref(tableRef)
		let c = dataRef.current ? $fn.copy(dataRef.current) : []
		let d = ref.data()
		let k = [ ...d, ...c ]
		ref.data(k,true)
		_onChange?.(k)
	}
	
	const onReset = () => {
		onceRef.current = 1
		const ref = $.ref(tableRef)
		let d = resetRef.current
		ref.data(d)
		_onChange?.(d)
	}

	const onEdit = () => {
		setEdit( v => !v)
	}
	
	useImperativeHandle( ref, () => ({
		edit:onEdit
	}))

	return (
		<Suspense>
			<div className='v'>
				{ 
					status === 0 || status === 2 ? (
						<div className='mb10 fx' style={{gap:'0 10px'}}>
							{
								status === 2 && <Button label={ edit ? '取消' : '编辑' } onClick={ onEdit } disabled={disabled} ghost width={60}/>
							}
							{
								( edit && status === 2 ) || status === 0 ? (
									<>
										<Button label='添加' onClick={ onAdd } disabled={disabled} ghost width={60}/>
										<Button label='删除' onClick={ onDel } disabled={disabled || keys?.length === 0} ghost width={60}/>
										<Button label='清空' onClick={ onClear } disabled={disabled || gray} ghost width={60}/>
										<Button label='重置' onClick={ onReset } disabled={disabled} ghost width={60}/>
									</>
								) : null
							}
						</div>
					) : null
				}
			</div>
			<div className='rel fv'>
				<Table {...table} ref={tableRef}/>
			</div>
		</Suspense>
	)
}

export default Index